import store from '../store/store';
import {system , browser} from '../common/js/system_browser';
let newHttp = function(options) {
  options.data = options.data ? options.data : {};
  options.data.system = system;
  options.data.browser = browser;
  let strData = function(obj) {
    // console.log('obj',obj);
    let data = JSON.parse(JSON.stringify(obj));
    if (data.noToast || data.noToast == false ) {
      delete data.noToast;
    }
    if (data.noLoading || data.noLoading == false) {
      delete data.noLoading;
    }
    if (data.timeout) {
      delete data.timeout;
    }
    if (data.async|| data.async == false) {
      delete data.async;
    }
    let dataStr = "";
    for (var key in data) {
      dataStr += key + '=' + encodeURIComponent(data[key]) + '&';
    }
    dataStr = dataStr && dataStr.slice(0, -1);
    return dataStr;
  };
  let open = function(xhr, type, url, async) {
    xhr.open(type, url, async);
  };
  let send = function(xhr, msg) {
    xhr.send(msg);
  };
  let setHeaders = function(xhr, headers) {
    if (options.type != 'FILE') {
      xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); //请求头部类型
    }
    // xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");//请求头部类型
    if (headers) {
      for (var key in headers) {
        xhr.setRequestHeader(key, headers[key]);
      }
    }
  };
  let createXHR = function() {
    return new XMLHttpRequest() || new ActiveXObject("Microsoft.XMLHTTP");
  };
  let request = function(xhr, opts) {
    if (opts.type === "GET") {
      opts.url = opts.url + '?' + strData(opts.data);
      open(xhr, "GET", opts.url, opts.async);
      if (opts.headers) {
        setHeaders(xhr, opts.headers);
      }
      send(xhr, null);
    }
    else if (opts.type === "POST") {
      open(xhr, "POST", opts.url, opts.async);
      if (opts.headers) {
        setHeaders(xhr, opts.headers);
      }
      send(xhr, strData(opts.data));
    }
    else if (opts.type === 'FILE') {
      open(xhr, 'POST', opts.url, opts.async);
      if (opts.headers) {
        setHeaders(xhr, opts.headers);
      }
      send(xhr, opts.data);
    }
  };
  let reminder = function(mes , IsForce) {
    let notoast = options.data.noToast || false;//是否是默认关闭提示
    let force = IsForce || false;//是否需要强制提示
    if( force ){
      require('../common/js/toast').toast(mes);
    }else if (!notoast) {
      require('../common/js/toast').toast(mes);
    }
  };
  let xhr = null;  // new xmlHttpRequest
  let newTimeout = null;//一个超时定时器
  let newRequest = function() {
    return new Promise(function(resolve, reject) {
      options.async = options.data.async || true; //同步false / 异步true
      options.data = options.data || {}; //ajax参数
      options.headers = options.headers || {}; //头部类型
      if (!options.data.noLoading) {
        store.commit('isLoading', true);
      }
      xhr = createXHR();
      xhr.onreadystatechange = function() {
        let res;
        if (xhr.readyState == 4) {
          clearTimeout(newTimeout);
          newTimeout = null;
          if (!options.data.noLoading) {
            store.commit('isLoading', false);
          }
          switch (xhr.status) {
            case 200:
              res = JSON.parse(xhr.responseText);
              let resCode = Number( res.code );
              // if( resCode != 505  ){
              //   store.commit('maintain',false);//隐藏维护通知
              // }
              // if( resCode != 506 ){
              //   store.commit('showCustomerNotice',false);//隐藏新老用户迁移通知
              // }
              switch ( resCode) {
                case 200:
                  break;
                case 443:
                  reminder('该操作需要登录!' , true );
                  store.commit('storageRemove', 'all'); //删除所有storage
                  store.commit('gologin', true);
                  break;
                case 3001:
                  reminder('该操作需要登录!' , true );
                  store.commit('storageRemove', 'all'); //删除所有storage
                  store.commit('gologin', true);
                  break;
                case 506:
                  store.commit('showCustomerNotice',true);//显示新老用户迁移通知
                  break;
                case 505:
                  store.commit('maintain',true);//显示维护通知
                  break;
                // case 609:
                //   break;
                default:
                  reminder(res.message);
              }
              resolve(res);
              break;
            default:
              try{
                res = JSON.parse(xhr.responseText);
              }catch(e){
                res = { 'err' : 'XMLHttpRequest请求错误' , xhrStatus : xhr.status };
                store.commit('isLoading', false);
              }
              if (res.message) {
                // reminder('请求错误！');
              }
              reject(res);
          }
        }
      };
      request(xhr, options);
    })
  };
  let timeout =  options.data.timeout || 10000 ; //设置请求超时时间 默认10秒
  let isNumber = function(val) {
    var regPos = /^\d+(\.\d+)?$/;
    var regNeg = /^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$/; //负浮点数
    if(regPos.test(val) || regNeg.test(val)) {
      return true;
    } else {
      return false;
    }
  };
  let requestTimeout = function() {
    //接口请求超时封装
    if( !isNumber(timeout) ){
      timeout = 10000;
    }
    return new Promise((resolve , reject) => {
      newTimeout = setTimeout(res => {
        clearTimeout(newTimeout);
        newTimeout = null;
        if( xhr ){
          xhr.abort();
        }
        reminder('请求超时!', true);
        store.commit('isLoading', false);
        reject( { data : { message : '请求超时' , timeout : true } } );
      }, Number(timeout) );
    })
  };
  return Promise.race([
    newRequest(), //http请求
    requestTimeout(), //超时promise
  ])
};
let post = function(options) {
  options.type = 'POST';
  return new newHttp(options);
};
let get = function(options) {
  options.type = 'GET';
  return new newHttp(options);
};
let file = function(options) {
  //瞎写的上传文件
  options.type = 'FILE';
  return new newHttp(options);
};

//option data 里面 可以传noToast = true (ajax不提示消息,有些ajax判断code较多或者reject情况自己选择提示消息)
//option data 里面 可以传noLoading = true (ajax不转菊花,防止有时候多个ajax一起调用会相互影响,选择在页面上自己控制)
//option data 里面 可以传timeout  设置请求超时时间 默认10000 10秒
export { post , get , file }
